import ZcoIMView from './view/ZcoIMView.vue';
import IMstate from './store/imState';
import Emoji from './utils/Emoji';
import VueI18n from 'vue-i18n';
import messages from './utils/language';

import zcoIMEvent from './store/event';
import { sendMessageToRecord, formatSessionMessageRecords, userInSessionRecord, setReceiveBusinessMessage } from '@/utils/message';
import Vue from 'vue';
import notifyMessage from './components/notify-message/notifyMessageJs';
Vue.prototype.$zcoMessage = notifyMessage;
import { updateMessageBoxHeight4Mobile, isMobile } from './utils/util';

class ZcoIm extends IMstate {
	instance = ZcoIm | null;
	getInstance () {
		// 判断系统是否已经有这个单例
		if (ZcoIm.instance === null) {
			ZcoIm.instance = new ZcoIm();
		}
		return ZcoIm.instance; // 单例模式
	}
	constructor() {
		super();
		this.container = null;
		this.wrapper = null;
		this.type = '';
		this.language = 'zh';
		this.i18n = null;
	}

	/**
	 * 初始化im组件，样式加载出来
	 * @param {number} width 宽
	 * @param {number} height 高
	 * @param {string} type 终端类型，如pc是电脑，mobile是手机。
	 * @param {string} ele 节点id
	 * @param {boolean} showBusinessMessage 是否显示业务指令消息
	 * @param {string[]} ignoreMessageType 需要屏蔽的指令消息type
	 */
	init (width, height, type, ele, showBusinessMessage, ignoreMessageType) {
		this.type = type;
		Vue.use(VueI18n);
		// Create VueI18n instance with options
		this.i18n = new VueI18n({
			locale: this.language, // set locale
			messages // set locale messages
		});
		console.log('zco-im: ZcomInInit', width, height, type, ele, new Date());
		this.setIMView(width, height, type);
		this.setShowBusinessMessage(showBusinessMessage);
		this.setIgnoreMessageType(ignoreMessageType);
		if (!this.vm) {
			this.ivcsDiv = document.createElement('div');
			this.ivcsDiv.id = 'ivcs-im-h5';
			const container = document.getElementById(ele);
			if (container) {
				this.container = container;
			} else {
				this.container = document.body;
			}
			this.container.appendChild(this.ivcsDiv);
			this.vm = new Vue({
				i18n: this.i18n,
				render: h => h(ZcoIMView)
			}).$mount('#ivcs-im-h5');
			Emoji.init();
		}
	}

	/**
	 * 设置多语言
	 * @param {string} lng
	 */
	setLanguage (lng) {
		this.language = lng;

		this.i18n.locale = lng;
		console.log('setLanguage:', this.i18n.locale, lng);
	}

	destory () {
		zcoIMEvent.removeAllListeners();
		if (this.container) {
			this.container.remove(this.ivcsDiv);
			this.container = null;
			this.vm = null;
			this.i18n = null;
		}
	}

	/**
	 * 调用方发送文本消息后，告知组件发送的结果。
	 * @param {object} data 消息内容
	 *  @param {string} status 消息状态 ok成功 failed 失败 down 下载成功
	 */
	sendMessage (data, status) {
		// 替换link的url
		if (this.resourceOriginUrlDomain && data.data && data.data.url && data.data.url.indexOf(this.resourceOriginUrlDomain) !== -1) {
			data.data.url = data.data.url.replace(this.resourceOriginUrlDomain, this.resourceReplaceUrlDomain);
		}
		if (Object.keys(this.urlMapping).length > 0) {
			Object.keys(this.urlMapping).forEach(key => {
				if (data.data && data.data.url && data.data.url.indexOf(key) !== -1) {
					data.data.url = data.data.url.replace(key, this.urlMapping[key]);
				}
			});
		}

		console.log('zco-im-sendMessage:', data, status, '+', new Date());
		if (status === 'ok') {
			this.chatMessage.forEach(item => {
				if (item.id === data.id) {
					item.status = 'ok';
				}
			});
		} else if (status === 'failed') {
			this.chatMessage.forEach(item => {
				if (item.id === data.id) {
					item.status = 'failed';
				}
			});
		} else if (status === 'down') {
			this.chatMessage.forEach(item => {
				if (item.id === data.id) {
					item.status = 'down';
				}
			});
		}
		console.log('zco-im-sendMessage-chatMessage:', this.chatMessage, '+', new Date());
		zcoIMEvent.updateChatMessage(this.chatMessage);
	}

	/**
	 * 调用方监听im组件内部点击发送消息事件。
	 * @param {function} ack ack 返回{data},data是具体的发送消息的消息数据
	 */
	onSendTextMessage (ack) {
		zcoIMEvent.onSendTextMessage(ack);
	}

	/**
	 * 调用方监听im组件内部点击发送资源文件事件。
	 * @param {function} ack ack 返回{data},data是具体的发送消息的消息数据
	 */
	onSendResourceMessage (ack) {
		zcoIMEvent.onSendResourceMessage(ack);
	}

	//修改聊天窗口的高度
	setChatMessageHeight (height) {
		if (this.type === 'web') {
			let ChatMessageDom = document.getElementById('chat-message');
			let webTitleDom = document.getElementById('web-title');
			let webFooterDom = document.getElementById('web-footer');
			let mobileFootDom = document.getElementById('mobile-footer');
			if (isMobile()) {
				ChatMessageDom.style.height = height - mobileFootDom.offsetHeight - 28 + 'px';
			} else {
				ChatMessageDom.style.height = height - webTitleDom.offsetHeight - webFooterDom.offsetHeight - 28 + 'px';
			}
		} else {
			updateMessageBoxHeight4Mobile(this.type);
		}
	}

	/**
	 * 设置im模块，自己的用户信息。userInfo{clientId,id,name,role,avatar....}，用于显示自己的用户名头像等。
	 * @param {object} userInfo
	 */
	setUserInfo (userInfo) {
		if (this.type === 'web') {
			this.setAgentData(userInfo);
		} else {
			this.setClientData(userInfo);
		}
	}

	/**
	 * 收到对方发送的文本消息。调用方执行后，组件内渲染消息内容。
	 * @param {object} message
	 */
	setReceiveTextMessage (message) {
		let data = null;
		let fromUser = {
			clientId: message.from,
			id: message.fromUser.id,
			isRobot: message.fromUser.isRobot,
			name: message.fromUser.name,
			role: message.fromUser.role,
			avatar: message.fromUser.avatar
		};
		switch (message.type) {
			case 'text':
				//文字
				data = sendMessageToRecord('text', Emoji.textFace2imgFace(message.data), fromUser, 'ok');
				break;
			case 'link':
				//图片
				data = sendMessageToRecord('link', message.data, fromUser, 'ok');
				// 替换link的url
				if (this.resourceOriginUrlDomain && data.data && data.data.url && data.data.url.indexOf(this.resourceOriginUrlDomain) !== -1) {
					data.data.url = data.data.url.replace(this.resourceOriginUrlDomain, this.resourceReplaceUrlDomain);
				}
				if (Object.keys(this.urlMapping).length > 0) {
					Object.keys(this.urlMapping).forEach(key => {
						if (data.data && data.data.url && data.data.url.indexOf(key) !== -1) {
							data.data.url = data.data.url.replace(key, this.urlMapping[key]);
						}
					});
				}
				break;
			default:
				break;
		}
		this.setChatMessage(data);
		console.log('zco-im-setReceiveTextMessage:', this.chatMessage, '+', new Date());
	}

	/**
	 * 清除组件数据
	 */
	clearZcoIMData () {
		this.chatMessage.splice(0, this.chatMessage.length);
		this.agent = null;
		this.client = null;
		this.maxUploadFileSize = null;
		console.log('zco-im-clearChatMessage:', this.chatMessage, '+', new Date());
		zcoIMEvent.updateChatMessage([]);
		zcoIMEvent.hangUp('hangup');
		zcoIMEvent.updateWebTitle({ title: '', type: '', members: 0 });
		zcoIMEvent.updateMobileTitle({ title: '', type: '', members: 0 });
	}

	/**
	 * 初始化的聊天记录
	 * @param {object} data 聊天记录
	 */
	setInitChatMessage (data) {
		data.forEach(item => {
			if (item.msgType === 'text') {
				item.data = Emoji.textFace2imgFace(item.data);
			}
		});
		let message = formatSessionMessageRecords(data);
		this.setChatMessage(message);
	}

	/**
	 * 设置用户加入或离开的信息
	 * 显示系统消息，如某某加入，某某离开。
	 * @param {object} data
	 */
	setSystemMessage (data) {
		let message = userInSessionRecord(data);
		this.setChatMessage(message);
	}

	/**
	 * 设置mobile title
	 * 设置聊天窗口的title
	 * @param {object} {title, type, members}  title : 标题文本, type： im | audio | video, members ： 在线人数
	 */
	setMobileTitle (data) {
		this.mobileTitle = data ? data.title : '';
		zcoIMEvent.updateMobileTitle(data);
	}

	/**
	 * 设置组件配置信息
	 * @param {object} options  maxUploadFileSize 上传文件最大值
	 * @param {string} resourceOriginUrlDomain 收到的资源文件的原始域名 eg:'ivcs-nginx'
	 * @param {string} resourceReplaceUrlDomain 需要替换的资源文件域名 eg:'ivcs-showcase-xxx'
	 */
	setOptions (options) {
		this.maxUploadFileSize = options.maxUploadFileSize;
		this.resourceOriginUrlDomain = options.resourceOriginUrlDomain ? options.resourceOriginUrlDomain : '';
		this.resourceReplaceUrlDomain = options.resourceReplaceUrlDomain ? options.resourceReplaceUrlDomain : '';
		this.hideVideoButton = options.hideVideoButton ? options.hideVideoButton : false;
		this.hidePhotoButton = options.hidePhotoButton ? options.hidePhotoButton : false;
		this.hideImageButton = options.hideImageButton ? options.hideImageButton : false;
		this.hideFileButton = options.hideFileButton ? options.hideFileButton : false;
		this.hideMoreButton = options.hideMoreButton ? options.hideMoreButton : false; // 隐藏更多按钮（+号）
		this.showKbButton = options.showKbButton ? options.showKbButton : false; // 显示知识库按钮
		this.urlMapping = options.urlMapping || {};
		// web端更新配置
		if (this.type === 'web' && this.vm && this.vm.$children[0] && this.vm.$children[0].updateOptions) {
			this.vm.$children[0].updateOptions();
		}
		console.log('im setOptions', options);
	}

	/**
	 *  关闭im 聊天 对话框回到通话中
	 * @param {Function} ack
	 */
	onUpdateColesImChatMessage (ack) {
		zcoIMEvent.onUpdateColesImChatMessage(ack);
	}

	setZcoIMStatus (opacity, zIndex) {
		const ZcoIMContainer = document.getElementById('zco-im');
		ZcoIMContainer.style.opacity = opacity;
		ZcoIMContainer.style.zIndex = zIndex;
	}

	/**
	 * 收到上传结束事件
	 * @param {Function} ack
	 */
	onUploadEnd (ack) {
		zcoIMEvent.onUploadEnd(ack);
	}

	//调用方收到sync-message消息进行存储数据
	setBusinessMessage (data) {
		// 系统开始双录消息不显示
		if (data && data.from === 'system' && ['start-recording', 'stop-recording', 'system-start-recording', 'system-stop-recording'].includes(data.msgType)) {
			return;
		}
		// showBusinessMessage为false时系统消息不显示
		if (!ZcoIM.showBusinessMessage) {
			return;
		}
		if (data.msgType === 'peer-response') {
			if (data.data.cmd === 'customer-view-mark') return; // 访客接受/拒绝实时标注
		}
		const message = setReceiveBusinessMessage(data, this.resourceOriginUrlDomain, this.resourceReplaceUrlDomain, this.urlMapping);
		this.setChatMessage(message);
	}

	/**
	 * 收到聊天窗口加载完成事件
	 * @param {Function} ack
	 */
	onChatViewMounted (ack) {
		zcoIMEvent.onChatViewMounted(ack);
	}

	/**
	 * 收到点击了挂断按钮事件
	 * @param {Function} ack
	 */
	onRequestHangup (ack) {
		zcoIMEvent.onRequestHangup(ack);
	}

	/**
	 * 收到点击了语音通话事件
	 * @param {Function} ack
	 */
	onRequestAudioCall (ack) {
		zcoIMEvent.onRequestAudioCall(ack);
	}

	/**
	 * 收到点击了视频通话事件
	 * @param {Function} ack
	 */
	onRequestVideoCall (ack) {
		zcoIMEvent.onRequestVideoCall(ack);
	}

	/**
	 * 设置呼叫类型
	 * @param {object} {title, type}  title : 标题文本, type： im | audio | video, members ： 在线人数
	 */
	setWebTitle (data) {
		zcoIMEvent.updateWebTitle(data);
	}

	/**
	 * 监听emoji显示|隐藏事件
	 */
	onEmojiShowHide (ack) {
		zcoIMEvent.onEmojiShowHide(ack);
	}

	/**
	 * 更新聊天窗口高度
	 */
	updateMessageBoxHeight () {
		updateMessageBoxHeight4Mobile(this.type);
	}

	/**
	 * 点击了知识库按钮
	 */
	onKbButtonClick (ack) {
		zcoIMEvent.onKbButtonClick(ack);
	}

	/**
	 * 坐席发送link消息给访客
	 * @param {*} link
	 */
	sendKbMessage (link) {
		if (!link) {
			console.log('sendKbMessage: link is null');
			return;
		}
		if (!ZcoIM.agent) {
			console.log('sendKbMessage: agent is null');
			return;
		}
		const data = sendMessageToRecord('text', link, ZcoIM.agent, 'in-progress');
		ZcoIM.setChatMessage(data);
		zcoIMEvent.emitTextMessage(data);
	}
}
const ZcoIM = new ZcoIm();
export default ZcoIM;
